﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace SARD.Aux_Forms
{
    public partial class brightrange : Form
    {
        int m, M;
        int oldm, oldM, size;
        int max, min;
        byte[] pixels8;
        ushort[] pixels16;

        public brightrange()
        {
            InitializeComponent();
        }

        /// <summary>
        /// Displays a form showing the maximum and minimum values of bright, these values can be changed displaying a new image where the pixels will be scaled within max and min.
        /// </summary>
        /// <param name="m">
        /// Minimum value of brighness
        /// </param>
        /// <param name="M">
        /// Maximum value of brighness
        /// </param>
        public brightrange( int m,  int M)
        {
            this.m = m;
            this.M = M;
            this.max = M;
            this.min = m;
            InitializeComponent();
            this.trackBar1.Maximum = M;
            this.trackBar2.Maximum = M;
            textBox1.Text = m.ToString();
            textBox2.Text = M.ToString();
            

        }

        /// <summary>
        /// Displays a form showing the maximum and minimum values of bright, these values can be changed displaying a new image where the pixels will be scaled within max and min.
        /// This function also have informations about the previous max and min values.
        /// </summary>
        /// <param name="m">
        /// Minimum value
        /// </param>
        /// <param name="M">
        /// Maximum value
        /// </param>
        /// <param name="om">
        /// Old minimum value
        /// </param>
        /// <param name="oM">
        /// Old maximum value
        /// </param>
        public brightrange(int m, int M, int om, int oM)
        {
            this.m = m;
            this.M = M;
            this.oldm = om;
            this.oldM = oM;
            this.max = M;
            this.min = m;
            InitializeComponent();
            this.trackBar1.Maximum = M;
            this.trackBar1.Minimum = m;
            this.trackBar2.Maximum = M;
            this.trackBar2.Minimum = m;
            textBox1.Text = oldm.ToString();
            textBox2.Text = oldM.ToString();


        }


        /// <summary>
        ///  Displays a form showing the maximum and minimum values of bright, these values can be changed displaying a new image where the pixels will be scaled within max and min.
        /// This function also have informations about the previous max and min values. It also has a preview function that will show a small image in the form.
        /// This image will be updated, allowing the user to see a previous image before coming back to the main window.
        /// </summary>
        /// <param name="m">
        /// Minimum value
        /// </param>
        /// <param name="M">
        /// Maximum value
        /// </param>
        /// <param name="om">
        /// Old minimum value
        /// </param>
        /// <param name="oM">
        /// Old maximum value
        /// </param>
        /// <param name="pixels">
        /// Ushort data
        /// </param>
        /// <param name="size">
        /// Desired image size (dimension)
        /// </param>
        public brightrange(int m, int M, int om, int oM, ushort[] pixels, int size)
        {
            this.m = m;
            this.M = M;
            this.oldm = om;
            this.oldM = oM;
            this.max = M;
            this.min = m;
            this.pixels8 = null;
            this.pixels16 = new ushort[size * size];

            InitializeComponent();

            this.trackBar1.Maximum = M;
            this.trackBar1.Minimum = m;
            this.trackBar2.Maximum = M;
            this.trackBar2.Minimum = m;
            this.size = size;
            textBox1.Text = oldm.ToString();
            textBox2.Text = oldM.ToString();

            for (int i = 0; i < size; i++)
                for (int j = 0; j < size; j++)
                    pixels16[i + j * size] = pixels[i + j * size];


            display16();


        }



        /// <summary>
        ///  Displays a form showing the maximum and minimum values of bright, these values can be changed displaying a new image where the pixels will be scaled within max and min.
        /// This function also have informations about the previous max and min values. It also has a preview function that will show a small image in the form.
        /// This image will be updated, allowing the user to see a previous image before coming back to the main window.
        /// </summary>
        /// <param name="m">
        /// Minimum value
        /// </param>
        /// <param name="M">
        /// Maximum value
        /// </param>
        /// <param name="om">
        /// Old minimum value
        /// </param>
        /// <param name="oM">
        /// Old maximum value
        /// </param>
        /// <param name="pixels">
        /// Byte data
        /// </param>
        /// <param name="size">
        /// Desired image size (dimension)
        /// </param>
        public brightrange(int m, int M, int om, int oM, byte[] pixels, int size)
        {
            this.m = m;
            this.M = M;
            this.max = M;
            this.min = m;
            this.oldm = om;
            this.oldM = oM;
            this.pixels8 = new byte[size * size];
            this.pixels16 = null;

            InitializeComponent();
            this.trackBar1.Maximum = M;
            this.trackBar1.Minimum = m;
            this.trackBar2.Maximum = M;
            this.trackBar2.Minimum = m;
            textBox1.Text = oldm.ToString();
            textBox2.Text = oldM.ToString();

            for (int i = 0; i < size; i++)
                for (int j = 0; j < size; j++)
                    pixels8[i + j * size] = pixels[i + j * size];

            display8();


        }


        /// <summary>
        /// This function updates the text box and the max and min values when they are changed.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void textBox2_TextChanged(object sender, EventArgs e)
        {
            int m2 = Convert.ToInt32(this.textBox2.Text);
            int m1 = Convert.ToInt32(this.textBox1.Text);
            this.trackBar2.Value = M - m2 + m1;
        }



        private void textBox1_TextChanged(object sender, EventArgs e)
        {
            int m2 = Convert.ToInt32(this.textBox1.Text);
            this.trackBar1.Value = m2;
        }



        private void trackBar2_Scroll(object sender, EventArgs e)
        {
            this.textBox2.Text = Convert.ToString(M - this.trackBar2.Value);
        }



        private void trackBar1_Scroll(object sender, EventArgs e)
        {
            this.textBox1.Text = this.trackBar1.Value.ToString();
        }



        private void button1_Click(object sender, EventArgs e)
        {
            min = Convert.ToInt32(textBox1.Text);
            max = Convert.ToInt32(textBox2.Text);
            if (pixels16 != null)
                display16();
            if(pixels8 != null)
                display8();

        }



        public int getmin()
        {
            return m;
        }



        public int getmax()
        {
            return M;
        }



        private void display16() 
        {
            Bitmap bmp = new Bitmap(size, size);
            double imagerange = Convert.ToDouble(max- min);

            bmp = new Bitmap(size, size, System.Drawing.Imaging.PixelFormat.Format24bppRgb);

            BitmapData bmd = bmp.LockBits(new Rectangle(0, 0, size, size), System.Drawing.Imaging.ImageLockMode.ReadOnly, bmp.PixelFormat);

            unsafe
            {

                double  b;

                for (int i = 0; i < bmd.Height; ++i)
                {
                    byte* row = (byte*)bmd.Scan0 + (i * bmd.Stride);
                    for (int j = 0; j < bmd.Width; ++j)
                    {
                        b = Convert.ToDouble(pixels16[i * bmd.Width + j] - min) * 255.0 / imagerange;

                        
                        if (b > 255)
                            b = 255;

                        if (b < 0)
                            b = 0;


                        row[j * 3] = (byte)b;            // Red
                        row[j * 3 + 1] = (byte)b;            // Green
                        row[j * 3 + 2] = (byte)b;            // Blue

                        
                    }
                }
            } // end unsafe   
            bmp.UnlockBits(bmd);
            pictureBox1.Image = bmp;
        }




        private void display8()
        {
            Bitmap bmp = new Bitmap(size, size);
            double imagerange = Convert.ToDouble(max - min);

            bmp = new Bitmap(size, size, System.Drawing.Imaging.PixelFormat.Format24bppRgb);

            BitmapData bmd = bmp.LockBits(new Rectangle(0, 0, size, size), System.Drawing.Imaging.ImageLockMode.ReadOnly, bmp.PixelFormat);

            unsafe
            {

                double b;

                for (int i = 0; i < bmd.Height; ++i)
                {
                    byte* row = (byte*)bmd.Scan0 + (i * bmd.Stride);
                    for (int j = 0; j < bmd.Width; ++j)
                    {
                        b = Convert.ToDouble(pixels8[i * bmd.Width + j] - min) * 255.0 / imagerange;

                       
                        if (b > 255)
                            b = 255;

                        if (b < 0)
                            b = 0;


                        row[j * 3] = (byte)b;            // Red
                        row[j * 3 + 1] = (byte)b;            // Green
                        row[j * 3 + 2] = (byte)b;            // Blue


                    }
                }
            } // end unsafe   
            bmp.UnlockBits(bmd);
            pictureBox1.Image = bmp;
        }



        private void button2_Click(object sender, EventArgs e)
        {
            M = max;
            m = min;
            this.Close();
        }
    }
}
